﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using Haozes.FxClient.Fetion2008;
using Haozes.FxClient.CommUtil;
using Haozes.FxClient.Security;
using Haozes.FxClient.Core;
using Haozes.FxClient.Sip;
using System.Threading;

namespace Haozes.FxClient
{
    public class LoginMgr
    {
        private User user;
        public event EventHandler<LoginEventArgs> LoginSucceed;
        public event EventHandler<LoginEventArgs> LoginFailed;

        public LoginMgr(User user)
        {
            this.user = user;
        }

        public void Login()
        {
            EventHandler<LoginEventArgs> handlerSuccess = this.LoginSucceed;
            EventHandler<LoginEventArgs> handlerFailed = this.LoginFailed;
            string password = this.user.HashedPassword;
            try
            {
                this.GetSysConfig(this.user.MobileNo.ToString());
                this.SSIAppSignIn(this.user.MobileNo.ToString(), password);
                this.SIPCSingIn();

                if (handlerSuccess != null)
                {
                    handlerSuccess(this, null);
                }
            }
            catch (Exception ex)
            {
                if (handlerFailed != null)
                {
                    handlerFailed(this, new LoginEventArgs(ex.ToString()));
                }
            }
        }

        private void GetSysConfig(string mobile)
        {
            // string configStr = TcpHelper.GetTcpClientResult("nav.fetion.com.cn", 80, postData, true);
            string postData = Fetion2008Template.GetSystemConfigPostData(mobile);
            string configStr = HttpHelper.Post("http://nav.fetion.com.cn/nav/getsystemconfig.aspx", postData);
            if (!string.IsNullOrEmpty(configStr))
            {
                this.user.CreateSipSysConfig(configStr);
            }
        }

        private void SSIAppSignIn(string mobile, string pwd)
        {
            string url = string.Format("{0}?mobileno={1}&domains=fetion.com.cn%3bm161.com.cn&digest={2}", this.user.SysConfig.SsiAppSignIn, mobile, pwd);
            string[] resultList = HttpHelper.Get(url, string.Empty);
            DebugWriter.WriteLine("step1:获取SSIC成功:");
            this.user.CreatePortInfo(resultList);
        }

        private void SIPCSingIn()
        {
            string nonce = this.SIPCSingInStep1();
            DebugWriter.WriteLine("step2:获取nonce成功");
            this.SIPCSingInStep2(nonce);
        }

        private string SIPCSingInStep1()
        {
            string sendData = Fetion2008Template.RegesterSIPCStep1(this.user.Uri.Sid.ToString());
            string[] addrStrArr = this.user.SysConfig.SipcProxy.Split(':');
            this.user.Conncetion.Connect(addrStrArr[0], addrStrArr[1]);
            string result = TcpHelper.SendAndReceive(this.user.Conncetion.SipSocket, sendData);
            return this.GetNonce(result);
        }

        private void SIPCSingInStep2(string nonce)
        {
            if (string.IsNullOrEmpty(nonce))
                return;
            ComputeAuthResponse response = new ComputeAuthResponse(this.user.Uri.Sid.ToString(), this.user.HashedPassword, this.user.Port.Domain, nonce, true);
            string cNonce = response.GetCNonce();
            string computResponse = response.ComputeResponse();

            string salt = this.user.HashedPassword.Substring(0, 8);
            string ssic = this.user.Port.Ssic;
            string sendData = Fetion2008Template.RegesterSIPCStep2(this.user.Uri.Sid.ToString(), computResponse, cNonce, salt, ssic);
            string result = TcpHelper.SendAndReceive(this.user.Conncetion.SipSocket, sendData);
            if (result.IndexOf("SIP-C/2.0 200 OK") >= 0)
            {
                DebugWriter.WriteLine("step2:Login To SIPC Server Successful!");
            }
            else
            {
                this.LoginFailed(this, new LoginEventArgs("step2:Login To SIPC Server failed"));
            }
        }

        private string GetNonce(string tcpResult)
        {
            string resultString = string.Empty;
            string pattern = @"nonce=\""(\w+?)\""";
            if (Regex.IsMatch(tcpResult, pattern))
            {
                resultString = Regex.Match(tcpResult, @"nonce=\""(\w+?)\""").Groups[1].Value;
            }
            else
            {
                this.LoginFailed(this, new LoginEventArgs("step2:Login To SIPC Server failed"));
            }
            return resultString;
        }
    }

    public class LoginEventArgs : EventArgs
    {
        private string description = string.Empty;

        public LoginEventArgs()
        { 
        }

        public LoginEventArgs(string description)
        {
            this.description = description;
        }

        public override string ToString()
        {
            return this.description;
        }
    }
}
